package com.filex.ads.nativeads;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;


import com.filex.ads.common.Preconditions;
import com.filex.ads.common.logging.Logger;

import org.json.JSONArray;
import org.json.JSONException;

import java.util.HashSet;
import java.util.Set;

public abstract class BaseNativeAd {

    public interface NativeEventListener {
        void onAdImpressed();
        void onAdClicked();
    }

    @NonNull final private Set<String> mImpressionTrackers;
    @NonNull final private Set<String> mClickTrackers;
    @Nullable private NativeEventListener mNativeEventListener;

    private boolean mInvalidated;

    protected BaseNativeAd() {
        mImpressionTrackers = new HashSet<String>();
        mClickTrackers = new HashSet<String>();
        mInvalidated = false;
    }

    public void setNativeEventListener(
            @Nullable final NativeEventListener nativeEventListener) {
        mNativeEventListener = nativeEventListener;
    }

    protected final void notifyAdImpressed() {
        if (mNativeEventListener != null) {
            mNativeEventListener.onAdImpressed();
        }
    }

    protected final void notifyAdClicked() {
        if (mNativeEventListener != null) {
            mNativeEventListener.onAdClicked();
        }
    }

    final protected void addImpressionTrackers(final Object impressionTrackers) throws ClassCastException {
        if (!(impressionTrackers instanceof JSONArray)) {
            throw new ClassCastException("Expected impression trackers of type JSONArray.");
        }

        final JSONArray trackers = (JSONArray) impressionTrackers;
        for (int i = 0; i < trackers.length(); i++) {
            try {
                addImpressionTracker(trackers.getString(i));
            } catch (JSONException e) {
                // This will only occur if we access a non-existent index in JSONArray.
                Logger.d("Unable to parse impression trackers.");
            }
        }
    }

    final protected void addClickTrackers(final Object clickTrackers) throws ClassCastException {
        if (!(clickTrackers instanceof JSONArray)) {
            throw new ClassCastException("Expected click trackers of type JSONArray.");
        }

        final JSONArray trackers = (JSONArray) clickTrackers;
        for (int i = 0; i < trackers.length(); i++) {
            try {
                addClickTracker(trackers.getString(i));
            } catch (JSONException e) {
                // This will only occur if we access a non-existent index in JSONArray.
                Logger.d("Unable to parse click trackers.");
            }
        }
    }

    final public void addImpressionTracker(@NonNull final String url) {
        if (!Preconditions.NoThrow.checkNotNull(url, "impressionTracker url is not allowed to be null")) {
            return;
        }
        mImpressionTrackers.add(url);
    }

    final public void addClickTracker(@NonNull final String url) {
        if (!Preconditions.NoThrow.checkNotNull(url, "clickTracker url is not allowed to be null")) {
            return;
        }
        mClickTrackers.add(url);
    }

    abstract void registerViewForAction(View view);

    abstract void unregisterViewForAction(View view);

    @NonNull
    Set<String> getImpressionTrackers() {
        return new HashSet<String>(mImpressionTrackers);
    }

    @NonNull
    Set<String> getClickTrackers() {
        return new HashSet<String>(mClickTrackers);
    }

    public void invalidate(){
        mInvalidated = true;
    }

    public boolean isInvalidated(){
        return mInvalidated;
    }

    public abstract void destroy();

    abstract String getTitle();

    abstract String getDesc();

    abstract String getDesc2();

    abstract String getSponsored();

    abstract String getLikes();

    abstract String getDownloads();

    abstract String getDisplayUrl();

    abstract String getMainImageUrl();

    abstract String getIconImageUrl();

    abstract String getCallToAction();

    abstract Double getStarRating() ;
}
